package com.xique.client.service.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xique.client.api.ITxLocationApi;
import com.xique.client.bean.domain.*;
import com.xique.client.bean.request.WxAppChangeCarTypeRequest;
import com.xique.client.bean.request.WxAppClientLastOrderInfoRequest;
import com.xique.client.bean.request.WxAppInLaneCancelRequest;
import com.xique.client.bean.request.WxAppInLanePassRequest;
import com.xique.client.bean.search.ParkInSearch;
import com.xique.client.bean.search.ParkLaneCodeSearch;
import com.xique.client.bean.search.ParkOnSearch;
import com.xique.client.bean.search.ParkOutSearch;
import com.xique.client.bean.vo.WxAppParkOrderVO;
import com.xique.client.service.biz.service.IClientCommandService;
import com.xique.client.service.biz.service.IWxAppClientService;
import com.xique.client.service.domain.service.IWxAppClientDomainService;
import com.xique.client.service.service.*;
import com.xique.common.core.utils.*;
import com.xique.common.core.utils.ip.IpUtils;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.common.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author shd
 * @create 2021/11/8 9:53
 */
@Service
public class WxAppClientServiceImpl implements IWxAppClientService {

    @Autowired
    private IParkLaneService parkLaneService;

    @Autowired
    private IParkLaneCodeService parkLaneCodeService;

    @Autowired
    private IParkDeviceNewService parkDeviceNewService;

    @Autowired
    private IPayOrderService payOrderService;

    @Autowired
    private IParkInService parkInService;

    @Autowired
    private IParkOutService parkOutService;

    @Autowired
    private IParkOnService parkOnService;

    @Autowired
    private AliossUtil aliossUtil;

    @Autowired
    private RedisService redisService;

    @Autowired
    private IWxAppClientDomainService wxAppClientDomainService;

    @Autowired
    private IClientCommandService clientCommandService;

    @Autowired
    private ITxLocationApi txLocationApi;

    @Value("${tx.location.api.key}")
    private String key;

    @Override
    public AjaxResult homePageInfo() {

        Long parkId = SecurityUtils.getParkId();
        Long userId = SecurityUtils.getUserId();
        String userName = SecurityUtils.getUsername();

        ParkDeviceNew parkDeviceNew = new ParkDeviceNew();
        parkDeviceNew.setParkId(parkId);
        parkDeviceNew.setIsMain("Y");
        parkDeviceNew.setStatus("normal");
        parkDeviceNew.setRecordStatus("normal");
        List<ParkDeviceNew> parkDeviceNewList = parkDeviceNewService.selectParkDeviceNewList(parkDeviceNew);
        ParkLane parkLane;
        if(!CollectionUtils.isEmpty(parkDeviceNewList)){
            for(ParkDeviceNew parkDeviceNew1 : parkDeviceNewList){
                parkLane = parkLaneService.selectParkLaneById(parkDeviceNew1.getLaneId());
                parkDeviceNew1.setLaneType(null != parkLane ? parkLane.getLaneType() : "0");
                parkDeviceNew1.setLaneName(null != parkLane ? parkLane.getName() : parkDeviceNew1.getName());
            }
        }

        Double cash = payOrderService.selectCashStatisticByUserId(parkId, userId);
        Double free = payOrderService.selectFreeStatisticByUserId(parkId, userId);

        Map<String, Object> statistic = new HashMap<>(4);
        statistic.put("cash", cash);
        statistic.put("free", free);
        statistic.put("userId", userId);
        statistic.put("userName", userName);

        Map<String, Object> response = new HashMap<>(2);
        response.put("statistic", statistic);
        response.put("lanes", parkDeviceNewList);

        return AjaxResult.success(response);
    }

    /**
     * 获取通道最近处理过的停车订单信息
     * @param laneId
     * @return
     */
    private JSONObject getLaneParkingOrder(Long laneId){
        String str = redisService.getCacheObject("jzy:lane:parkingOrder:" + laneId);
        if(StringUtils.isNotEmpty(str)){
            return JSONObject.parseObject(str);
        }else{
            return null;
        }
    }

    private void delLaneParkingOrder(Long laneId) {
        redisService.deleteObject("jzy:lane:parkingOrder:" + laneId);
    }

    @Override
    public AjaxResult orderInfo(WxAppClientLastOrderInfoRequest request) {

        JSONObject object = getLaneParkingOrder(request.getLaneId());
        if (null == object) {
            return AjaxResult.success("该通道没有订单",null);
        }
        ParkingOrder parkingOrder = object.getObject("ParkingOrder", ParkingOrder.class);
        if (StringUtils.isEmpty(parkingOrder.getParkingSerial())) {
            return AjaxResult.error("该订单没有流水号");
        }

        ParkOutSearch parkOutSearch = new ParkOutSearch();
        parkOutSearch.setParkingSerial(parkingOrder.getParkingSerial());
        ParkOut parkOut = parkOutService.selectParkOut(parkOutSearch);

        ParkInSearch parkInSearch = new ParkInSearch();
        parkInSearch.setParkingSerial(parkingOrder.getParkingSerial());
        if (null != parkOut) {
            parkInSearch.setId(parkOut.getInId());
        }
        ParkIn parkIn = parkInService.selectParkIn(parkInSearch);

        ParkDeviceNew parkDeviceNew = new ParkDeviceNew();
        parkDeviceNew.setLaneId(request.getLaneId());
        parkDeviceNew.setIsMain("Y");
        parkDeviceNew.setStatus("normal");
        parkDeviceNew.setRecordStatus("normal");
        List<ParkDeviceNew> parkDeviceNewList = parkDeviceNewService.selectParkDeviceNewList(parkDeviceNew);

        Long laneId = object.getLong("laneId");
        ParkLane parkLane = parkLaneService.selectParkLaneById(laneId);

        ParkLaneCodeSearch parkLaneCodeSearch = new ParkLaneCodeSearch();
        parkLaneCodeSearch.setLaneId(request.getLaneId());
        ParkLaneCode parkLaneCode = parkLaneCodeService.selectParkLaneCode(parkLaneCodeSearch);

        WxAppParkOrderVO vo = OrikaUtil.convert(parkingOrder, WxAppParkOrderVO.class);
        if (null != parkIn) {
            vo.setInPic(aliossUtil.getJzyGetObjectUrl(parkIn.getInPic()).toString());
            vo.setCarType(parkIn.getCarType());
        }
        if (null != parkOut) {
            vo.setOutPic(aliossUtil.getJzyGetObjectUrl(parkOut.getOutPic()).toString());
            vo.setOutTime(parkOut.getOutTime());
        }
        if (!CollectionUtils.isEmpty(parkDeviceNewList)) {
            ParkDeviceNew deviceNew = parkDeviceNewList.get(0);
            vo.setDeviceCode(deviceNew.getCode());
        }
        if (StringUtils.isNotNull(parkLaneCode)) {
            vo.setQrCodeUrl(parkLaneCode.getUrl());
        }
        vo.setPayLaneId(request.getLaneId());
        vo.setLaneType(parkLane.getLaneType());

        return AjaxResult.success(vo);
    }

    @Override
    public AjaxResult changeCarType(WxAppChangeCarTypeRequest request) {

        String parkingSerial = request.getParkingSerial();

        ParkOut parkOutUpdate = null;
        ParkIn parkInUpdate = null;
        if (StringUtils.equals("in", request.getType())) {
            ParkInSearch parkInSearch = new ParkInSearch();
            parkInSearch.setParkingSerial(parkingSerial);
            ParkIn parkIn = parkInService.selectParkIn(parkInSearch);

            parkInUpdate = new ParkIn();
            parkInUpdate.setId(parkIn.getId());
            parkInUpdate.setCarType(request.getCarType());
        }

        if (StringUtils.equals("out", request.getType())) {

            ParkOutSearch parkOutSearch = new ParkOutSearch();
            parkOutSearch.setParkingSerial(parkingSerial);
            ParkOut parkOut = parkOutService.selectParkOut(parkOutSearch);

            parkOutUpdate = new ParkOut();
            parkOutUpdate.setId(parkOut.getId());
            parkOutUpdate.setCarType(request.getCarType());

            ParkInSearch parkInSearch = new ParkInSearch();
            parkInSearch.setParkingSerial(parkingSerial);
            if (null != parkOut) {
                parkInSearch.setId(parkOut.getInId());
            }
            ParkIn parkIn = parkInService.selectParkIn(parkInSearch);

            parkInUpdate = new ParkIn();
            parkInUpdate.setId(parkIn.getId());
            parkInUpdate.setCarType(request.getCarType());
        }

        boolean isSuccess = wxAppClientDomainService.changeCarType(parkInUpdate, parkOutUpdate);
        if (!isSuccess) {
            return AjaxResult.error();
        }

        return AjaxResult.success();
    }

    @Override
    public AjaxResult inLanePass(WxAppInLanePassRequest request) {

        // 修改入场记录状态 在场记录状态 开闸
        ParkInSearch parkInSearch = new ParkInSearch();
        parkInSearch.setParkingSerial(request.getParkingSerial());
        ParkIn parkIn = parkInService.selectParkIn(parkInSearch);

        ParkIn updateParkIn = new ParkIn();
        updateParkIn.setId(parkIn.getId());
        updateParkIn.setInType("5");
        updateParkIn.setStatus("42");
        updateParkIn.setInRemark("确认放行");

        ParkOnSearch parkOnSearch = new ParkOnSearch();
        parkOnSearch.setParkingSerial(request.getParkingSerial());
        ParkOn parkOn = parkOnService.selectParkOn(parkOnSearch);

        ParkOn updateParkOn = null;
        if (StringUtils.isNotNull(parkOn)) {
            updateParkOn = new ParkOn();
            updateParkOn.setId(parkOn.getId());
            updateParkOn.setInStatus("42");
            updateParkOn.setInRemark("确认放行");
        }

        AjaxResult result = clientCommandService.openGate(request.getDeviceCode());
        if (!Arrays.asList(0, 1).contains(Integer.parseInt(result.get("result_code").toString()))) {
            return AjaxResult.error(result.get("message").toString());
        }

        boolean isSuccess = wxAppClientDomainService.inLanePass(updateParkIn, updateParkOn);
        if (!isSuccess) {
            return AjaxResult.error();
        }

        delLaneParkingOrder(parkIn.getInLaneId());

        return AjaxResult.success();
    }

    @Override
    public AjaxResult inLaneCancel(WxAppInLaneCancelRequest request) {

        // 修改入场记录状态 在场记录状态
        ParkInSearch parkInSearch = new ParkInSearch();
        parkInSearch.setParkingSerial(request.getParkingSerial());
        ParkIn parkIn = parkInService.selectParkIn(parkInSearch);

        ParkIn updateParkIn = new ParkIn();
        updateParkIn.setId(parkIn.getId());
        updateParkIn.setInType("6");
        updateParkIn.setStatus("43");
        updateParkIn.setInRemark("取消放行");

        ParkOnSearch parkOnSearch = new ParkOnSearch();
        parkOnSearch.setParkingSerial(request.getParkingSerial());
        ParkOn parkOn = parkOnService.selectParkOn(parkOnSearch);

        Long updateParkOnId = null;
        if (StringUtils.isNotNull(parkOn)) {
            updateParkOnId = parkOn.getId();
        }

        boolean isSuccess = wxAppClientDomainService.inLaneCancel(updateParkIn, updateParkOnId);
        if (!isSuccess) {
            return AjaxResult.error();
        }

        delLaneParkingOrder(parkIn.getInLaneId());

        return AjaxResult.success();
    }

    @Override
    public AjaxResult getAddressByIp() {

        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());

        Map<String, Object> map = new HashMap<>(2);
        map.put("key", key);
        map.put("ip", ip);

        JSONObject json = txLocationApi.getAddressByIp(map);

        if (0 != json.getInteger("status")) {
            return AjaxResult.error("获取位置失败");
        }

        JSONObject result = json.getJSONObject("result");
        JSONObject adInfo = result.getJSONObject("ad_info");
        String province = adInfo.getString("province");

        return AjaxResult.success("获取成功", province);
    }
}
